// 路由全局前置导航守卫
import router, { asyncRoutes } from '@/router'
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import store from '@/store'

const whiteList = ['/login', '/404']

// 你们的项目里面如何获取用户信息的？
// 用户信息里面有用户uid。
// 判断是否有用户uid。
// 如果没有就获取用户信息。
// vuex里面设置一个用户信息,调用。
router.beforeEach(async(to, from, next) => {
//   to去哪里
//   from从哪里来
//   next放行
  Nprogress.start()
  const token = store.getters.token
  console.log(token)
  if (token) {
    if (to.path === '/login') {
      next('/')
    } else {
      // 从vuex取当前的用户信息
      // 如果没有获取到用户信息，
      if (!store.getters.userId) {
        // 为什么要用await: 因为获取用户信息是异步的，如果不用await，那么就会直接执行next()，跳转到目标页面的时候，没有用户信息
        // 用户资料里面有当前用户拥有的页面权限信息 >> 获取这些权限信息
        const res = await store.dispatch('user/getUserInfo')
        // console.log(res)
        // 进行动态路由匹配和筛选
        console.log(res.roles.menus) // 当前用户拥有的页面权限信息
        console.log(asyncRoutes) // 所有的动态路由 >> 根据当前用户拥有的页面权限信息，进行筛选
        // 当前用户所拥有的动态路由数组
        const filterRoutes = asyncRoutes.filter(item => {
          return res.roles.menus.includes(item.meta.name)
        })
        // 把筛选之后的动态路由数组调用mutations方法存储到vuex >> 渲染左侧菜单
        // 1、页面访问权限
        // 2、菜单权限
        // 3、按钮权限
        // 4、api接口权限
        store.commit('user/setRoutes', filterRoutes)
        // 添加到路由表里面去
        // 注意点：404的路由要放到页面的最后面 >> 静态路由里面的404要删除掉
        // 访问具体的路径的时候，能够展示对应的页面
        router.addRoutes(
          [
            ...filterRoutes,
            // 404的路由必须放到路由表的最后面，不然刷新可能出现404
            { path: '*', redirect: '/404', hidden: true }
          ])
        //   重新跳转一次
        next(to.path) // 添加完以后重新跳转一次即可 >> vue-router已知的bug
        console.log(router)
      }
      next()
    }
  } else {
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
    }
  }
  Nprogress.done()
})

router.afterEach(() => {
  console.log('23')
  // 关闭进度条
  Nprogress.done()
})

// const fn = function() {
//   console.log(this)
// }

// 如果函数内部的this希望指向到外层，只能用箭头函数
// const a = () => {
//   console.log(this)
// }

// 我们项目里面其实也是有代码规范的，如果函数内部不会用到this，必须全部用到箭头函数。
